package com.pororo.smartoff;

import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.app.Service;
import android.app.admin.DevicePolicyManager;
import android.content.ContentResolver;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.AsyncTask;
import android.os.IBinder;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;

public class SmartOffService extends Service implements SensorEventListener {
	final static String TAG = "SmartOffService";
	final int SLEEP_TIME = 500;
	
	private SensorManager sensorManager;
    private Sensor proximitySensor;
    
    private SmartOffPhoneStateListener phoneStateListener;
    private TelephonyManager telephonyManager;
 
    SmartOffTask offTask;
    boolean checkRinging = false;
    boolean isStopService = false;
    String topActivityName = null;
    int checkCount = 0;
    int callStatus = 0;
    
    //PowerManager.WakeLock wakeLock;
	
	@Override
	public void onCreate() {
		super.onCreate();
		
		Log.i(TAG, "onCreate");

		sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
		proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
		
		telephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
		phoneStateListener = new SmartOffPhoneStateListener();
		telephonyManager.listen(phoneStateListener, SmartOffPhoneStateListener.LISTEN_CALL_STATE);
		
		offTask = new SmartOffTask();
		//Use when service die
//		PowerManager pm = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
//		wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "SmartOff");
//		wakeLock.acquire();
	}
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		Log.i(TAG, "onStartCommand");
		
//		SENSOR_DELAY_FASTEST: 18-20 msec
//		SENSOR_DELAY_GAME: 37-39 msec
//		SENSOR_DELAY_UI: 85-87 msec
//		SENSOR_DELAY_NORMAL: 215-230 msec
		
		sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
		offTask.execute(0);		
		
		topActivityName = intent.getStringExtra("TopActivityName");
		Log.d(TAG, "Service get TopActivity :" + topActivityName);
				
		return START_NOT_STICKY;
	}
	
	@Override
	public void onDestroy() {
		Log.i(TAG, "onDestory");
		isStopService = true;
		sensorManager.unregisterListener(this);
		telephonyManager.listen(phoneStateListener, SmartOffPhoneStateListener.LISTEN_NONE);
		
		offTask.runningThread = false;
		offTask.cancel(true);
	
		//wakeLock.release();
		super.onDestroy();
	}
	
	@Override
	public IBinder onBind(Intent intent) {
		return null;
	}

	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		
	}

	@Override
	public void onSensorChanged(SensorEvent event) {
		Log.i(TAG, "onSensorChagned");
		
		if(Sensor.TYPE_PROXIMITY == event.sensor.getType()) {
			Log.i(TAG,"근접  : "+event.values[0]);
			
			if ( event.values[0] > 0.0f ) {
				stopService();
			} 
				
		}	
	}
	
	public void stopService() {
		isStopService = true;
		offTask.runningThread = false;
		offTask.cancel(true);
		this.stopSelf();
	}
	
	@SuppressLint("NewApi")
	public void OffScreen() {
		Log.i(TAG, "offScreen");
		isStopService = true;
		SmartOffPreferences.setBoolean("SaveTopPackage", false);

		try {	    	
	    	ContentResolver cr = getContentResolver();	    	
	    	int time = Settings.System.getInt(cr, Settings.System.SCREEN_OFF_TIMEOUT);
	    	if ( time > 300000 ) {
	    		time = 300000;
	    	}
	    	time = (time - (checkCount * SLEEP_TIME))/1000;
	    	Log.i(TAG, "Save Time : "+ time);
	    	SmartOffDBHelper.increaseAppCount(this, topActivityName, time);			
		} catch (SettingNotFoundException e) {
			e.printStackTrace();
		}
		
		
		KeyguardManager keyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE);
		KeyguardManager.KeyguardLock keyguardLock = keyguardManager.newKeyguardLock(KEYGUARD_SERVICE);
		
		DevicePolicyManager localDCM = (DevicePolicyManager)getSystemService("device_policy");
		
		if (keyguardManager.isKeyguardLocked()) {
			Log.d(TAG, "devicePolicyManager.lockNow()");
			localDCM.lockNow();
		} else {
			Log.d(TAG, "LOCK DISABLE!!");
			keyguardLock.disableKeyguard();
			localDCM.lockNow();
			keyguardLock.reenableKeyguard();
		}
	}
	
	public class SmartOffTask extends AsyncTask<Integer, Integer, Integer> {
		public boolean runningThread;
		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			runningThread = true;
		}
		
		@Override
		protected Integer doInBackground(Integer... arg) {
			while (runningThread) {
				try {
					Thread.sleep(SLEEP_TIME);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				checkCount++;
				Log.d(TAG, "Check Sensor Count : " + checkCount);
				
				if ( checkRinging == true ) {
					Log.d(TAG, "TaskLoop Delay because of Calling");
					checkCount = 0;
				}
				
				if (checkCount >= 4) {
					runningThread = false;
					break;
				}				
			}
			return checkCount;
		}
		
		@Override
		protected void onPostExecute(Integer result) {
			super.onPostExecute(result);
			OffScreen();
		}
	}
	
	
	public class SmartOffPhoneStateListener extends PhoneStateListener {
		public void onCallStateChanged(int state, String incomingNumber) {
			String stateStr = "";
			
			switch (state) {
			case TelephonyManager.CALL_STATE_IDLE:
				stateStr = "Idle";
				callStatus = state;
				if ( checkRinging == true ) {
					checkRinging = false;
					offTask = new SmartOffTask();
					offTask.execute(0);
				}
				break;
			case TelephonyManager.CALL_STATE_RINGING:
				stateStr = "Ringing";
				callStatus = state;
				checkRinging = true;
				offTask.runningThread = false;
				offTask.cancel(true);				
				break;	
			case TelephonyManager.CALL_STATE_OFFHOOK:
				stateStr = "Offhook";
				callStatus = state;
				stopService();
				break;
			}
			
			Log.i(TAG, "Call Status : " + stateStr);
		}
	}
}